use super::AttributeInfo;


// LocalVariableTable_attribute {
//     u2 attribute_name_index;
//     u4 attribute_length;
//     u2 local_variable_table_length;
//     {   u2 start_pc; // 生命周期开始的字节码偏移量
//         u2 length; // 覆盖范围长度
//         u2 name_index;
//         u2 descriptor_index;
//         u2 index; // 栈帧的局部变量表中变量槽的位置
//     } local_variable_table[local_variable_table_length];
// }

// 用于描述栈帧中局部变量表的变量与Java源码中定义的变量之间的关系

// 默认生成，可在javac中通过使用-g：none或-g：vars选项来取消或要求生成这项信息。

// 如果没有生成这项属性，最大的影响就是当其他人引用这个方法时，所有的参数名称都将会丢失，
// 譬如IDE将会使用诸如arg0、arg1之类的占位符代替原有的参数名，这对程序运行没有影响，
// 但是会对代码编写带来较大不便，而且在调试期间无法根据参数名称从上下文中获得参数值。

pub struct LocalVariableTableAttribute {
    local_variable_table: Vec<LocalVariableTableEntry>
}

impl AttributeInfo for LocalVariableTableAttribute {
    fn read_info(&mut self, reader: &mut crate::classfile::ClassReader) {
        let line_number_table_length = reader.read_u16();
        for _ in 0..line_number_table_length {
            self.local_variable_table.push(
                LocalVariableTableEntry { 
                    start_pc: reader.read_u16(), 
                    length: reader.read_u16(), 
                    name_index: reader.read_u16(), 
                    descriptor_index: reader.read_u16(), 
                    index: reader.read_u16()
                }
            )
        }
    }
}

impl LocalVariableTableAttribute {
    pub fn new() -> LocalVariableTableAttribute {
        LocalVariableTableAttribute { local_variable_table: vec![] }
    }
}

// start_pc和length属性分别代表了这个局部变量的生命周期开始的字节码偏移量及其作用范围覆盖的长度，两者结合起来就是这个局部变量在字节码之中的作用域范围。
// name_index和descriptor_index都是指向常量池中CONSTANT_Utf8_info型常量的索引，分别代表了局部变量的名称以及这个局部变量的描述符。

#[allow(warnings)]
pub struct LocalVariableTableEntry {
    start_pc: u16,
    length: u16,
    name_index: u16,
    descriptor_index: u16,
    index: u16
}